
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>pymatgen.util.provenance &#8212; pymatgen 2020.7.3 documentation</title>
    <link rel="stylesheet" href="../../../_static/basic.css" type="text/css" />
    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
    <script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
    <script src="../../../_static/jquery.js"></script>
    <script src="../../../_static/underscore.js"></script>
    <script src="../../../_static/doctools.js"></script>
    <script src="../../../_static/language_data.js"></script>
    <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />
 
<script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-33990148-1']);
  _gaq.push(['_trackPageview']);
</script>

  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../index.html">pymatgen 2020.7.3 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="../../pymatgen.html" accesskey="U">pymatgen</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">pymatgen.util.provenance</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
          <div class="body" role="main">
            
  <h1>Source code for pymatgen.util.provenance</h1><div class="highlight"><pre>
<span></span><span class="c1"># coding: utf-8</span>
<span class="c1"># Copyright (c) Pymatgen Development Team.</span>
<span class="c1"># Distributed under the terms of the MIT License.</span>

<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Classes and methods related to the Structure Notation Language (SNL)</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">namedtuple</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">StringIO</span>
<span class="kn">from</span> <span class="nn">monty.json</span> <span class="kn">import</span> <span class="n">MontyDecoder</span><span class="p">,</span> <span class="n">MontyEncoder</span>
<span class="kn">from</span> <span class="nn">monty.string</span> <span class="kn">import</span> <span class="n">remove_non_ascii</span>

<span class="kn">from</span> <span class="nn">pymatgen.core.structure</span> <span class="kn">import</span> <span class="n">Structure</span><span class="p">,</span> <span class="n">Molecule</span>
<span class="kn">from</span> <span class="nn">pybtex.database.input</span> <span class="kn">import</span> <span class="n">bibtex</span>
<span class="kn">from</span> <span class="nn">pybtex</span> <span class="kn">import</span> <span class="n">errors</span>


<span class="n">__author__</span> <span class="o">=</span> <span class="s1">&#39;Anubhav Jain, Shyue Ping Ong&#39;</span>
<span class="n">__credits__</span> <span class="o">=</span> <span class="s1">&#39;Dan Gunter&#39;</span>
<span class="n">__copyright__</span> <span class="o">=</span> <span class="s1">&#39;Copyright 2013, The Materials Project&#39;</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s1">&#39;0.1&#39;</span>
<span class="n">__maintainer__</span> <span class="o">=</span> <span class="s1">&#39;Anubhav Jain&#39;</span>
<span class="n">__email__</span> <span class="o">=</span> <span class="s1">&#39;ajain@lbl.gov&#39;</span>
<span class="n">__date__</span> <span class="o">=</span> <span class="s1">&#39;Feb 11, 2013&#39;</span>


<span class="n">MAX_HNODE_SIZE</span> <span class="o">=</span> <span class="mi">64000</span>  <span class="c1"># maximum size (bytes) of SNL HistoryNode</span>
<span class="n">MAX_DATA_SIZE</span> <span class="o">=</span> <span class="mi">256000</span>  <span class="c1"># maximum size (bytes) of SNL data field</span>
<span class="n">MAX_HNODES</span> <span class="o">=</span> <span class="mi">100</span>  <span class="c1"># maximum number of HistoryNodes in SNL file</span>
<span class="n">MAX_BIBTEX_CHARS</span> <span class="o">=</span> <span class="mi">20000</span>  <span class="c1"># maximum number of characters for BibTeX reference</span>


<div class="viewcode-block" id="is_valid_bibtex"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.is_valid_bibtex">[docs]</a><span class="k">def</span> <span class="nf">is_valid_bibtex</span><span class="p">(</span><span class="n">reference</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Use pybtex to validate that a reference is in proper BibTeX format</span>

<span class="sd">    Args:</span>
<span class="sd">        reference: A String reference in BibTeX format.</span>

<span class="sd">    Returns:</span>
<span class="sd">        Boolean indicating if reference is valid bibtex.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c1"># str is necessary since pybtex seems to have an issue with unicode. The</span>
    <span class="c1"># filter expression removes all non-ASCII characters.</span>
    <span class="n">sio</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">(</span><span class="n">remove_non_ascii</span><span class="p">(</span><span class="n">reference</span><span class="p">))</span>
    <span class="n">parser</span> <span class="o">=</span> <span class="n">bibtex</span><span class="o">.</span><span class="n">Parser</span><span class="p">()</span>
    <span class="n">errors</span><span class="o">.</span><span class="n">set_strict_mode</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
    <span class="n">bib_data</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_stream</span><span class="p">(</span><span class="n">sio</span><span class="p">)</span>
    <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="n">bib_data</span><span class="o">.</span><span class="n">entries</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span></div>


<div class="viewcode-block" id="HistoryNode"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.HistoryNode">[docs]</a><span class="k">class</span> <span class="nc">HistoryNode</span><span class="p">(</span><span class="n">namedtuple</span><span class="p">(</span><span class="s1">&#39;HistoryNode&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s1">&#39;url&#39;</span><span class="p">,</span> <span class="s1">&#39;description&#39;</span><span class="p">])):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A HistoryNode represents a step in the chain of events that lead to a</span>
<span class="sd">    Structure. HistoryNodes leave &#39;breadcrumbs&#39; so that you can trace back how</span>
<span class="sd">    a Structure was created. For example, a HistoryNode might represent pulling</span>
<span class="sd">    a Structure from an external database such as the ICSD or CSD. Or, it might</span>
<span class="sd">    represent the application of a code (e.g. pymatgen) to the Structure, with</span>
<span class="sd">    a custom description of how that code was applied (e.g. a site removal</span>
<span class="sd">    Transformation was applied).</span>

<span class="sd">    A HistoryNode contains three fields:</span>

<span class="sd">    .. attribute:: name</span>

<span class="sd">        The name of a code or resource that this Structure encountered in</span>
<span class="sd">        its history (String)</span>

<span class="sd">    .. attribute:: url</span>

<span class="sd">        The URL of that code/resource (String)</span>

<span class="sd">    .. attribute:: description</span>

<span class="sd">        A free-form description of how the code/resource is related to the</span>
<span class="sd">        Structure (dict).</span>
<span class="sd">    &quot;&quot;&quot;</span>

<div class="viewcode-block" id="HistoryNode.as_dict"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.HistoryNode.as_dict">[docs]</a>    <span class="k">def</span> <span class="nf">as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns: Dict</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s2">&quot;url&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">url</span><span class="p">,</span>
                <span class="s2">&quot;description&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">description</span><span class="p">}</span></div>

<div class="viewcode-block" id="HistoryNode.from_dict"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.HistoryNode.from_dict">[docs]</a>    <span class="nd">@staticmethod</span>
    <span class="k">def</span> <span class="nf">from_dict</span><span class="p">(</span><span class="n">h_node</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Args:</span>
<span class="sd">            d (dict): Dict representation</span>

<span class="sd">        Returns:</span>
<span class="sd">            HistoryNode</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">HistoryNode</span><span class="p">(</span><span class="n">h_node</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">],</span> <span class="n">h_node</span><span class="p">[</span><span class="s1">&#39;url&#39;</span><span class="p">],</span>
                           <span class="n">h_node</span><span class="p">[</span><span class="s1">&#39;description&#39;</span><span class="p">])</span></div>

<div class="viewcode-block" id="HistoryNode.parse_history_node"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.HistoryNode.parse_history_node">[docs]</a>    <span class="nd">@staticmethod</span>
    <span class="k">def</span> <span class="nf">parse_history_node</span><span class="p">(</span><span class="n">h_node</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Parses a History Node object from either a dict or a tuple.</span>

<span class="sd">        Args:</span>
<span class="sd">            h_node: A dict with name/url/description fields or a 3-element</span>
<span class="sd">                tuple.</span>

<span class="sd">        Returns:</span>
<span class="sd">            History node.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">h_node</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
            <span class="k">return</span> <span class="n">HistoryNode</span><span class="o">.</span><span class="n">from_dict</span><span class="p">(</span><span class="n">h_node</span><span class="p">)</span>

        <span class="k">else</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">h_node</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">3</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Invalid History node, &quot;</span>
                                 <span class="s2">&quot;should be dict or (name, version, &quot;</span>
                                 <span class="s2">&quot;description) tuple: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">h_node</span><span class="p">))</span>
            <span class="k">return</span> <span class="n">HistoryNode</span><span class="p">(</span><span class="n">h_node</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">h_node</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">h_node</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span></div></div>


<div class="viewcode-block" id="Author"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.Author">[docs]</a><span class="k">class</span> <span class="nc">Author</span><span class="p">(</span><span class="n">namedtuple</span><span class="p">(</span><span class="s1">&#39;Author&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s1">&#39;email&#39;</span><span class="p">])):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    An Author contains two fields:</span>

<span class="sd">    .. attribute:: name</span>

<span class="sd">        Name of author (String)</span>

<span class="sd">    .. attribute:: email</span>

<span class="sd">        Email of author (String)</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        String representation of an Author</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="s1">&#39;</span><span class="si">{}</span><span class="s1"> &lt;</span><span class="si">{}</span><span class="s1">&gt;&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">email</span><span class="p">)</span>

<div class="viewcode-block" id="Author.as_dict"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.Author.as_dict">[docs]</a>    <span class="k">def</span> <span class="nf">as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns: MSONable dict.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s2">&quot;email&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">email</span><span class="p">}</span></div>

<div class="viewcode-block" id="Author.from_dict"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.Author.from_dict">[docs]</a>    <span class="nd">@staticmethod</span>
    <span class="k">def</span> <span class="nf">from_dict</span><span class="p">(</span><span class="n">d</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Args:</span>
<span class="sd">            d (dict): Dict representation</span>

<span class="sd">        Returns:</span>
<span class="sd">            Author</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Author</span><span class="p">(</span><span class="n">d</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">],</span> <span class="n">d</span><span class="p">[</span><span class="s1">&#39;email&#39;</span><span class="p">])</span></div>

<div class="viewcode-block" id="Author.parse_author"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.Author.parse_author">[docs]</a>    <span class="nd">@staticmethod</span>
    <span class="k">def</span> <span class="nf">parse_author</span><span class="p">(</span><span class="n">author</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Parses an Author object from either a String, dict, or tuple</span>

<span class="sd">        Args:</span>
<span class="sd">            author: A String formatted as &quot;NAME &lt;email@domain.com&gt;&quot;,</span>
<span class="sd">                (name, email) tuple, or a dict with name and email keys.</span>

<span class="sd">        Returns:</span>
<span class="sd">            An Author object.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">author</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
            <span class="c1"># Regex looks for whitespace, (any name), whitespace, &lt;, (email),</span>
            <span class="c1"># &gt;, whitespace</span>
            <span class="n">m</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;\s*(.*?)\s*&lt;(.*?@.*?)&gt;\s*&#39;</span><span class="p">,</span> <span class="n">author</span><span class="p">)</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">m</span> <span class="ow">or</span> <span class="n">m</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">m</span><span class="o">.</span><span class="n">end</span><span class="p">()</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">author</span><span class="p">):</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Invalid author format! </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">author</span><span class="p">))</span>
            <span class="k">return</span> <span class="n">Author</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">groups</span><span class="p">()[</span><span class="mi">0</span><span class="p">],</span> <span class="n">m</span><span class="o">.</span><span class="n">groups</span><span class="p">()[</span><span class="mi">1</span><span class="p">])</span>
        <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">author</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
            <span class="k">return</span> <span class="n">Author</span><span class="o">.</span><span class="n">from_dict</span><span class="p">(</span><span class="n">author</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">author</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Invalid author, should be String or (name, &quot;</span>
                                 <span class="s2">&quot;email) tuple: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">author</span><span class="p">))</span>
            <span class="k">return</span> <span class="n">Author</span><span class="p">(</span><span class="n">author</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">author</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></div></div>


<div class="viewcode-block" id="StructureNL"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.StructureNL">[docs]</a><span class="k">class</span> <span class="nc">StructureNL</span><span class="p">:</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    The Structure Notation Language (SNL, pronounced &#39;snail&#39;) is container</span>
<span class="sd">    for a pymatgen Structure/Molecule object with some additional fields for</span>
<span class="sd">    enhanced provenance. It is meant to be imported/exported in a JSON file</span>
<span class="sd">    format with the following structure:</span>

<span class="sd">    - about</span>
<span class="sd">        - created_at</span>
<span class="sd">        - authors</span>
<span class="sd">        - projects</span>
<span class="sd">        - references</span>
<span class="sd">        - remarks</span>
<span class="sd">        - data</span>
<span class="sd">        - history</span>
<span class="sd">    - lattice (optional)</span>
<span class="sd">    - sites</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">struct_or_mol</span><span class="p">,</span> <span class="n">authors</span><span class="p">,</span> <span class="n">projects</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">references</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span>
                 <span class="n">remarks</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">history</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">created_at</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Args:</span>
<span class="sd">            struct_or_mol: A pymatgen.core.structure Structure/Molecule object</span>
<span class="sd">            authors: *List* of {&quot;name&quot;:&#39;&#39;, &quot;email&quot;:&#39;&#39;} dicts,</span>
<span class="sd">                *list* of Strings as &#39;John Doe &lt;johndoe@gmail.com&gt;&#39;,</span>
<span class="sd">                or a single String with commas separating authors</span>
<span class="sd">            projects: List of Strings [&#39;Project A&#39;, &#39;Project B&#39;]</span>
<span class="sd">            references: A String in BibTeX format</span>
<span class="sd">            remarks: List of Strings [&#39;Remark A&#39;, &#39;Remark B&#39;]</span>
<span class="sd">            data: A free form dict. Namespaced at the root level with an</span>
<span class="sd">                underscore, e.g. {&quot;_materialsproject&quot;: &lt;custom data&gt;}</span>
<span class="sd">            history: List of dicts - [{&#39;name&#39;:&#39;&#39;, &#39;url&#39;:&#39;&#39;, &#39;description&#39;:{}}]</span>
<span class="sd">            created_at: A datetime object</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># initialize root-level structure keys</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">structure</span> <span class="o">=</span> <span class="n">struct_or_mol</span>

        <span class="c1"># turn authors into list of Author objects</span>
        <span class="n">authors</span> <span class="o">=</span> <span class="n">authors</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">)</span>\
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">authors</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="n">authors</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">authors</span> <span class="o">=</span> <span class="p">[</span><span class="n">Author</span><span class="o">.</span><span class="n">parse_author</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">authors</span><span class="p">]</span>

        <span class="c1"># turn projects into list of Strings</span>
        <span class="n">projects</span> <span class="o">=</span> <span class="n">projects</span> <span class="k">if</span> <span class="n">projects</span> <span class="k">else</span> <span class="p">[]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">projects</span> <span class="o">=</span> <span class="p">[</span><span class="n">projects</span><span class="p">]</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">projects</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="n">projects</span>

        <span class="c1"># check that references are valid BibTeX</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">references</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Invalid format for SNL reference! Should be &quot;</span>
                             <span class="s2">&quot;empty string or BibTeX string.&quot;</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">references</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">is_valid_bibtex</span><span class="p">(</span><span class="n">references</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Invalid format for SNL reference! Should be &quot;</span>
                             <span class="s2">&quot;BibTeX string.&quot;</span><span class="p">)</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">references</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">MAX_BIBTEX_CHARS</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;The BibTeX string must be fewer than </span><span class="si">{}</span><span class="s2"> chars &quot;</span>
                             <span class="s2">&quot;, you have </span><span class="si">{}</span><span class="s2">&quot;</span>
                             <span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">MAX_BIBTEX_CHARS</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">references</span><span class="p">)))</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">references</span> <span class="o">=</span> <span class="n">references</span>

        <span class="c1"># turn remarks into list of Strings</span>
        <span class="n">remarks</span> <span class="o">=</span> <span class="n">remarks</span> <span class="k">if</span> <span class="n">remarks</span> <span class="k">else</span> <span class="p">[]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">remarks</span> <span class="o">=</span> <span class="p">[</span><span class="n">remarks</span><span class="p">]</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">remarks</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="n">remarks</span>

        <span class="c1"># check remarks limit</span>
        <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">remarks</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">140</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;The remark exceeds the maximum size of&quot;</span>
                                 <span class="s2">&quot;140 characters: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">r</span><span class="p">))</span>

        <span class="c1"># check data limit</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span> <span class="k">if</span> <span class="n">data</span> <span class="k">else</span> <span class="p">{}</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">sys</span><span class="o">.</span><span class="n">getsizeof</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">MAX_DATA_SIZE</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;The data dict exceeds the maximum size limit of&quot;</span>
                             <span class="s2">&quot; </span><span class="si">{}</span><span class="s2"> bytes (you have </span><span class="si">{}</span><span class="s2">)&quot;</span>
                             <span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">MAX_DATA_SIZE</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">getsizeof</span><span class="p">(</span><span class="n">data</span><span class="p">)))</span>

        <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">k</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;_&quot;</span><span class="p">):</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;data must contain properly namespaced data &quot;</span>
                                 <span class="s2">&quot;with keys starting with an underscore. The &quot;</span>
                                 <span class="s2">&quot;key </span><span class="si">{}</span><span class="s2"> does not start with an underscore.&quot;</span><span class="p">,</span>
                                 <span class="nb">format</span><span class="p">(</span><span class="n">k</span><span class="p">))</span>

        <span class="c1"># check for valid history nodes</span>
        <span class="n">history</span> <span class="o">=</span> <span class="n">history</span> <span class="k">if</span> <span class="n">history</span> <span class="k">else</span> <span class="p">[]</span>  <span class="c1"># initialize null fields</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">MAX_HNODES</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;A maximum of </span><span class="si">{}</span><span class="s2"> History nodes are supported, &quot;</span>
                             <span class="s2">&quot;you have </span><span class="si">{}</span><span class="s2">!&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">MAX_HNODES</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">history</span><span class="p">)))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">history</span> <span class="o">=</span> <span class="p">[</span><span class="n">HistoryNode</span><span class="o">.</span><span class="n">parse_history_node</span><span class="p">(</span><span class="n">h</span><span class="p">)</span> <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="n">history</span><span class="p">]</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">all</span><span class="p">([</span><span class="n">sys</span><span class="o">.</span><span class="n">getsizeof</span><span class="p">(</span><span class="n">h</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">MAX_HNODE_SIZE</span> <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="n">history</span><span class="p">]):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;One or more history nodes exceeds the maximum &quot;</span>
                             <span class="s2">&quot;size limit of </span><span class="si">{}</span><span class="s2"> bytes&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">MAX_HNODE_SIZE</span><span class="p">))</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">created_at</span> <span class="o">=</span> <span class="n">created_at</span> <span class="k">if</span> <span class="n">created_at</span> \
            <span class="k">else</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span>

<div class="viewcode-block" id="StructureNL.as_dict"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.StructureNL.as_dict">[docs]</a>    <span class="k">def</span> <span class="nf">as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns: MSONable dict</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">structure</span><span class="o">.</span><span class="n">as_dict</span><span class="p">()</span>
        <span class="n">d</span><span class="p">[</span><span class="s2">&quot;@module&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__module__</span>
        <span class="n">d</span><span class="p">[</span><span class="s2">&quot;@class&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span>
        <span class="n">d</span><span class="p">[</span><span class="s2">&quot;about&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;authors&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">a</span><span class="o">.</span><span class="n">as_dict</span><span class="p">()</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">authors</span><span class="p">],</span>
                      <span class="s2">&quot;projects&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">projects</span><span class="p">,</span>
                      <span class="s2">&quot;references&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">references</span><span class="p">,</span>
                      <span class="s2">&quot;remarks&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">remarks</span><span class="p">,</span>
                      <span class="s2">&quot;history&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">h</span><span class="o">.</span><span class="n">as_dict</span><span class="p">()</span> <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="p">],</span>
                      <span class="s2">&quot;created_at&quot;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">created_at</span><span class="p">,</span>
                                               <span class="bp">cls</span><span class="o">=</span><span class="n">MontyEncoder</span><span class="p">))}</span>
        <span class="n">d</span><span class="p">[</span><span class="s2">&quot;about&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">,</span>
                                                <span class="bp">cls</span><span class="o">=</span><span class="n">MontyEncoder</span><span class="p">)))</span>
        <span class="k">return</span> <span class="n">d</span></div>

<div class="viewcode-block" id="StructureNL.from_dict"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.StructureNL.from_dict">[docs]</a>    <span class="nd">@classmethod</span>
    <span class="k">def</span> <span class="nf">from_dict</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Args:</span>
<span class="sd">            d (dict): Dict representation</span>

<span class="sd">        Returns:</span>
<span class="sd">            Class</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">a</span> <span class="o">=</span> <span class="n">d</span><span class="p">[</span><span class="s2">&quot;about&quot;</span><span class="p">]</span>
        <span class="n">dec</span> <span class="o">=</span> <span class="n">MontyDecoder</span><span class="p">()</span>

        <span class="n">created_at</span> <span class="o">=</span> <span class="n">dec</span><span class="o">.</span><span class="n">process_decoded</span><span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;created_at&quot;</span><span class="p">))</span>
        <span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">d</span><span class="p">[</span><span class="s2">&quot;about&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
                <span class="k">if</span> <span class="n">k</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;_&quot;</span><span class="p">)}</span>
        <span class="n">data</span> <span class="o">=</span> <span class="n">dec</span><span class="o">.</span><span class="n">process_decoded</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>

        <span class="n">structure</span> <span class="o">=</span> <span class="n">Structure</span><span class="o">.</span><span class="n">from_dict</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> <span class="k">if</span> <span class="s2">&quot;lattice&quot;</span> <span class="ow">in</span> <span class="n">d</span> \
            <span class="k">else</span> <span class="n">Molecule</span><span class="o">.</span><span class="n">from_dict</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
        <span class="k">return</span> <span class="bp">cls</span><span class="p">(</span><span class="n">structure</span><span class="p">,</span> <span class="n">a</span><span class="p">[</span><span class="s2">&quot;authors&quot;</span><span class="p">],</span> <span class="n">projects</span><span class="o">=</span><span class="n">a</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;projects&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span>
                   <span class="n">references</span><span class="o">=</span><span class="n">a</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;references&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">),</span>
                   <span class="n">remarks</span><span class="o">=</span><span class="n">a</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;remarks&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
                   <span class="n">history</span><span class="o">=</span><span class="n">a</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;history&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span> <span class="n">created_at</span><span class="o">=</span><span class="n">created_at</span><span class="p">)</span></div>

<div class="viewcode-block" id="StructureNL.from_structures"><a class="viewcode-back" href="../../../pymatgen.util.provenance.html#pymatgen.util.provenance.StructureNL.from_structures">[docs]</a>    <span class="nd">@classmethod</span>
    <span class="k">def</span> <span class="nf">from_structures</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">structures</span><span class="p">,</span> <span class="n">authors</span><span class="p">,</span> <span class="n">projects</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                        <span class="n">references</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">remarks</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                        <span class="n">histories</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">created_at</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        A convenience method for getting a list of StructureNL objects by</span>
<span class="sd">        specifying structures and metadata separately. Some of the metadata</span>
<span class="sd">        is applied to all of the structures for ease of use.</span>

<span class="sd">        Args:</span>
<span class="sd">            structures: A list of Structure objects</span>
<span class="sd">            authors: *List* of {&quot;name&quot;:&#39;&#39;, &quot;email&quot;:&#39;&#39;} dicts,</span>
<span class="sd">                *list* of Strings as &#39;John Doe &lt;johndoe@gmail.com&gt;&#39;,</span>
<span class="sd">                or a single String with commas separating authors</span>
<span class="sd">            projects: List of Strings [&#39;Project A&#39;, &#39;Project B&#39;]. This</span>
<span class="sd">                applies to all structures.</span>
<span class="sd">            references: A String in BibTeX format. Again, this applies to all</span>
<span class="sd">                structures.</span>
<span class="sd">            remarks: List of Strings [&#39;Remark A&#39;, &#39;Remark B&#39;]</span>
<span class="sd">            data: A list of free form dict. Namespaced at the root level</span>
<span class="sd">                with an underscore, e.g. {&quot;_materialsproject&quot;:&lt;custom data&gt;}</span>
<span class="sd">                . The length of data should be the same as the list of</span>
<span class="sd">                structures if not None.</span>
<span class="sd">            histories: List of list of dicts - [[{&#39;name&#39;:&#39;&#39;, &#39;url&#39;:&#39;&#39;,</span>
<span class="sd">                &#39;description&#39;:{}}], ...] The length of histories should be the</span>
<span class="sd">                same as the list of structures if not None.</span>
<span class="sd">            created_at: A datetime object</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">data</span> <span class="o">=</span> <span class="p">[{}]</span> <span class="o">*</span> <span class="nb">len</span><span class="p">(</span><span class="n">structures</span><span class="p">)</span> <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">data</span>
        <span class="n">histories</span> <span class="o">=</span> <span class="p">[[]]</span> <span class="o">*</span> <span class="nb">len</span><span class="p">(</span><span class="n">structures</span><span class="p">)</span> <span class="k">if</span> <span class="n">histories</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> \
            <span class="n">histories</span>

        <span class="n">snl_list</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">struct</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">structures</span><span class="p">):</span>
            <span class="n">snl</span> <span class="o">=</span> <span class="n">StructureNL</span><span class="p">(</span><span class="n">struct</span><span class="p">,</span> <span class="n">authors</span><span class="p">,</span> <span class="n">projects</span><span class="o">=</span><span class="n">projects</span><span class="p">,</span>
                              <span class="n">references</span><span class="o">=</span><span class="n">references</span><span class="p">,</span>
                              <span class="n">remarks</span><span class="o">=</span><span class="n">remarks</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">],</span>
                              <span class="n">history</span><span class="o">=</span><span class="n">histories</span><span class="p">[</span><span class="n">i</span><span class="p">],</span>
                              <span class="n">created_at</span><span class="o">=</span><span class="n">created_at</span><span class="p">)</span>
            <span class="n">snl_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">snl</span><span class="p">)</span>

        <span class="k">return</span> <span class="n">snl_list</span></div>

    <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s2">&quot;</span><span class="si">{}</span><span class="se">\n</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">k</span><span class="p">))</span>
                          <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;structure&quot;</span><span class="p">,</span> <span class="s2">&quot;authors&quot;</span><span class="p">,</span> <span class="s2">&quot;projects&quot;</span><span class="p">,</span>
                                    <span class="s2">&quot;references&quot;</span><span class="p">,</span> <span class="s2">&quot;remarks&quot;</span><span class="p">,</span> <span class="s2">&quot;data&quot;</span><span class="p">,</span> <span class="s2">&quot;history&quot;</span><span class="p">,</span>
                                    <span class="s2">&quot;created_at&quot;</span><span class="p">)])</span>

    <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="nb">all</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span> <span class="o">==</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">n</span><span class="p">),</span>
                       <span class="p">(</span><span class="s2">&quot;structure&quot;</span><span class="p">,</span> <span class="s2">&quot;authors&quot;</span><span class="p">,</span> <span class="s2">&quot;projects&quot;</span><span class="p">,</span> <span class="s2">&quot;references&quot;</span><span class="p">,</span>
                        <span class="s2">&quot;remarks&quot;</span><span class="p">,</span> <span class="s2">&quot;data&quot;</span><span class="p">,</span> <span class="s2">&quot;history&quot;</span><span class="p">,</span> <span class="s2">&quot;created_at&quot;</span><span class="p">)))</span>

    <span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span></div>
</pre></div>

            <div class="clearer"></div>
          </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../../index.html">pymatgen 2020.7.3 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="../../pymatgen.html" >pymatgen</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">pymatgen.util.provenance</a></li> 
      </ul>
    </div>

    <div class="footer" role="contentinfo">
        &#169; Copyright 2011, Pymatgen Development Team.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.1.2.
    </div>
<div class="footer">This page uses <a href="http://analytics.google.com/">
Google Analytics</a> to collect statistics. You can disable it by blocking
the JavaScript coming from www.google-analytics.com.
<script type="text/javascript">
  (function() {
    var ga = document.createElement('script');
    ga.src = ('https:' == document.location.protocol ?
              'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    ga.setAttribute('async', 'true');
    document.documentElement.firstChild.appendChild(ga);
  })();
</script>
</div>

  </body>
</html>